package ext.tianma.part.AVLMaterial.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import ext.tianma.workflow.WorkflowUtil;
import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import wt.content.ApplicationData;
import wt.content.ContentHelper;
import wt.content.ContentItem;
import wt.content.ContentRoleType;
import wt.doc.WTDocument;
import wt.doc.WTDocumentMaster;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.fc.collections.WTHashSet;
import wt.folder.Folder;
import wt.httpgw.URLFactory;
import wt.inf.container.WTContainer;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.State;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.part.WTPartReferenceLink;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.workflow.engine.ProcessData;
import wt.workflow.engine.WfEngineHelper;
import wt.workflow.engine.WfProcess;

import com.ptc.windchill.enterprise.part.commands.PartDocServiceCommand;

import ext.com.iba.IBAUtil;
import ext.generic.erp.attributes.EnumerationUtil;
import ext.tianma.bom.service.MaterialsApplicationService;
import ext.tianma.bom.service.partQuantity.QuantityConfig;
import ext.tianma.bom.service.partQuantity.QuantityService;
import ext.tianma.bom.util.DBUtil;
import ext.tianma.bom.util.GenericUtil;
import ext.tianma.doc.SendOut.Interfaces.InterfaceService;
import ext.tianma.model.APLQuantity;
import ext.tianma.number.util.PartUtil;
import ext.tianma.part.AVLMaterial.AVLUtil;
import ext.tianma.part.AVLMaterial.constants.RangeChangeConstants;
import ext.tianma.part.AVLMaterial.process.RangeChangeProcess;
import ext.tianma.upload.CreateDocAndDescribeLink;
import ext.tianma.upload.MyUtil;
import ext.tianma.upload.creatDocuments;
import ext.tianma.util.TMUtil;
import ext.tianma.util.UserUtil;
import ext.tianma.workflow.BomWorkFlowUtil;
import ext.workflow.WorkFlowUtil;
import wt.workflow.work.WfAssignedActivity;

/**
 * 类名: AVLMaterialService </br>
 * 包名: ext.tianma.part.AVLMaterial.service
 * 描述: APL材料扩展：Service
 * @author xucr
 * 创建时间: 2020年7月24日
 * 发布版本: V1.0
 */
public class AVLMaterialService {
	
	public static final String RANGE = "range";//范围，对应属性内部名称
	public static final String RANGE_VALUE = "rangeValue";//范围，对应属性显示名称
	public static final String TARGETLEVEL = "targetLevel"; //目标等级，对应等级枚举key
	public static final String TARGETLEVEL_VALUE = "targetLevelValue"; //目标等级，对应等级枚举value
	public static final String HISTORYLEVEL = "historyLevel";//历史等级，对应等级枚举key
	public static final String HISTORYLEVEL_VALUE = "historyLevelValue";//历史等级，对应等级枚举value
	public static final String QUANTITY = "quantity";
	
	public static final String RANGES = "ranges";
	public static final String DATA = "data";

	/**
	 * 构造流程节点中的上载链接
	 * @param self
	 * @param pbo
	 * @param key
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年7月24日
	 */
	public static String getUpLoadUrl(ObjectReference self, Persistable pbo, int key) throws WTException {
		String str = "";
		String baseHref = new URLFactory().getBaseHREF();

		ReferenceFactory rf = new ReferenceFactory();
		WfProcess process = BomWorkFlowUtil.getProcess(self);
		String wid = rf.getReferenceString(process);

		if (pbo instanceof WTPart) {//APL材料审批流程：主对象是部件
			WTPart part = (WTPart) pbo;
			String oid = rf.getReferenceString(part);
			switch (key) {
				case 0:
					str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
							+ "netmarkets/jsp/part/AVLMaterial/upload.jsp?oid=" + oid + "&wid=" + wid
							+ "&docKey=appDoc', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
							+ "上载" + "</a>";
					break;
	
				default:
					break;
			}
		} else if(pbo instanceof WTDocument) {//APL材料用量进阶流程：主对象是文档
			WTDocument doc = (WTDocument) pbo;
			String oid = rf.getReferenceString(doc);
			switch (key) {
				case 0:
					str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
							+ "netmarkets/jsp/part/AVLMaterial/upload1.jsp?oid=" + oid + "&wid=" + wid
							+ "&docKey=appDoc', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
							+ "上载报告" + "</a>";
					break;
				case 1:
					str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
						+ "netmarkets/jsp/ext/BOMECO/tianma/materialPages/APL/showAdvanceInfo.html?oid=" + oid + "&wid=" + wid
						+ "&pageType=edit', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
						+ "进阶修改" + "</a>";
					break;
				case 2:
//					ApplicationData primary = InterfaceService.getPrimaryContent(doc);
//					if(null != primary) {
//						str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
//								+ "servlet/AttachmentsDownloadDirectionServlet?oid=" + oid + "&oid=" + TMUtil.obj2Oid(primary)
//								+ "&role=PRIMARY', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
//								+ "查看报告" + "</a>";
//					} else {
//						str = "未上载报告";
//					}
					QueryResult qr = ContentHelper.service.getContentsByRole(doc, ContentRoleType.SECONDARY);
					if(qr.size() > 0) {
						while(qr.hasMoreElements()) {
							ContentItem attachment = (ContentItem) qr.nextElement();
							if(attachment instanceof ApplicationData) {
								ApplicationData appData = (ApplicationData) attachment;
								str += "<a href=\"Javascript:var processWindow = window.open('" + baseHref
									+ "servlet/AttachmentsDownloadDirectionServlet?oid=" + oid + "&cioids=" + TMUtil.obj2Oid(appData)
									+ "&role=SECONDARY', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
									+ appData.getFileName() + "</a></br>";
							 }
						}
					} else {
						str = "未上载报告";
					}
					break;
				case 4:
					str = "<a href=\"Javascript:var processWindow = window.open('" + baseHref
						+ "netmarkets/jsp/ext/BOMECO/tianma/materialPages/APL/showAdvanceInfo.html?oid=" + oid + "&wid=" + wid
						+ "&pageType=read', '_blank', 'resizable=no,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no');\">"
						+ "进阶查看" + "</a>";
					break;
	
				default:
					break;
			}
		}
		return str;
	}
	
	
	/**
	 * 设置【材料创建者发起进阶申请】环节责任人
	 * @param self
	 * @author xucr
	 * @CreateDate 2020年11月18日
	 */
	public static void setRole(ObjectReference self, String roleName) {
		/**
		 * 如果APL材料创建者是管理员，则设定指定用户
		 * 否则，则由材料创建者来完成
		 * 
		 * 如果流程最终还是扭转到了管理员，则有可能是人员信息获取异常
		 * */
		try {
			WfProcess process = BomWorkFlowUtil.getProcess(self);
			WTPartMaster partMaster = (WTPartMaster) process.getContext().getValue(RangeChangeConstants.PARTMASTER);
			WTPart wtpart = PartUtil.getWTPartByNumber(partMaster.getNumber());
			if("Administrator".equals(wtpart.getCreatorName())) {
				List<WTUser> users = new ArrayList<WTUser>();
				WTUser user = getUser();
				users.add(user);
				WorkFlowUtil.addPrincipalToRole(process, roleName, users, true);
			}
		} catch (WTException e) {
			e.printStackTrace();
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 得到配置中的用户信息
	 * @return
	 * @author xucr
	 * @CreateDate 2020年11月18日
	 */
	public static WTUser getUser() {
		String userName = QuantityConfig.getUserName();
		WTUser user = null;
		try {
			user = UserUtil.getUserByName(userName);
		} catch (WTException e) {
			user = null;
			e.printStackTrace();
		}
		return user;
	}
	
	/**
	 * 校验是否有主内容
	 * @param pbo
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年11月18日
	 */
	public static boolean isExistPrimary(Persistable pbo) throws WTException {
		boolean isPrimary = false;
		if(pbo instanceof WTDocument) {
			WTDocument doc = (WTDocument) pbo;
			ApplicationData primary = InterfaceService.getPrimaryContent(doc);
			if(null != primary) {
				isPrimary = true;
			}
		}
		return isPrimary;
	}
	
	
	/**
	 * APL用量正常结束流程
	 * @param self
	 * @param pbo
	 * @param route 完成/取消
	 * @author xucr
	 * @CreateDate 2020年11月12日
	 */
	public static void completeProcess(ObjectReference self, Persistable pbo, String route) {
		/**
		 * 流程结束时处理：
		 * 取消
		 * 		状况为【异常】，是否流程中为【否】，用量高，未进阶
		 * 通过
		 * 		a.状况为【正常】，是否流程中为【否】，完成进阶
		 * 		b.上载的报告归档，关联到APL材料中：参考文档
		 * 		c.同步更新APL材料中对应范围的等级
		 * 		d.同步更新用量表的等级
		 * */
		WTDocument doc = (WTDocument) pbo;
		WfProcess process = BomWorkFlowUtil.getProcess(self);
		String changeData = (String) process.getContext().getValue(RangeChangeConstants.CHANGEDATA);
		WTPartMaster partMaster = (WTPartMaster) process.getContext().getValue(RangeChangeConstants.PARTMASTER);
		try {
			JSONArray array = new JSONArray(changeData);
			if("cancel".equals(route)) {
				cancel(array, partMaster, doc, route);
			} else if("complete".equals(route)) {
				String firstRange = (String) process.getContext().getValue(RangeChangeConstants.FIRSTPROCESSRANGE);
				agree(array, firstRange, partMaster, doc, route);
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 正常完成
	 * @param array
	 * @param partMaster
	 * @param doc
	 * @param route
	 * @author xucr
	 * @CreateDate 2020年11月12日
	 */
	private static void agree(JSONArray array,String firstRange, WTPartMaster partMaster, WTDocument doc, String route) {
		/**
		 * 	a.状况为【正常】，是否流程中为【否】，完成进阶
		 * 	b.上载的报告归档，关联到APL材料中：参考文档
		 * 	c.同步更新APL材料中对应范围的等级
		 * 	d.同步更新用量表的等级
		 * */
		WTHashSet set = new WTHashSet();
		try {
			Hashtable<String, String> table = getChangeRangeData(array, partMaster, route, set);
			//修改用量表
			if(set.size() > 0) {
				PersistenceHelper.manager.save(set);
			}
			//修改APL材料等级
			if(table.size() > 0) {
				WTPart wtpart = PartUtil.getWTPartByNumber(partMaster.getNumber());
				//归档报告
				WTDocumentMaster docMaster = (WTDocumentMaster) doc.getMaster();	
				WTPartReferenceLink refLink = WTPartReferenceLink.newWTPartReferenceLink(wtpart, docMaster);
				PersistenceServerHelper.manager.insert(refLink);
				//更新属性
				IBAUtil.forceSetIBAValues(wtpart, table);
			}
			//将首次变更填入的，在提交节点删除的，需要将流程状态设置为非流程中
			delUpdateISProcess(array, firstRange, partMaster);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 流程取消
	 * @param array
	 * @param partMaster
	 * @param doc
	 * @param route
	 * @author xucr
	 * @CreateDate 2020年11月12日
	 */
	private static void cancel(JSONArray array, WTPartMaster partMaster, WTDocument doc, String route) {
		/**
		 * 状况为【异常】，是否流程中为【否】，用量高，未进阶
		 * */
		WTHashSet set = new WTHashSet();
		try {
			getChangeRangeData(array, partMaster, route, set);
			if(set.size() > 0) {
				PersistenceHelper.manager.save(set);
			}
		} catch (WTException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 得到流程中的变更数据，并更新到用量对象中
	 * @param array
	 * @param partMaster
	 * @param route
	 * @param set
	 * @author xucr
	 * @CreateDate 2020年11月12日
	 */
	private static Hashtable<String, String> getChangeRangeData(JSONArray array, WTPartMaster partMaster, String route, WTHashSet set) {
		Hashtable<String, String> table = new Hashtable<String, String>();//要更新到实际对象中的范围、等级
		try {
			JSONObject obj = null;
			
			//如果指定材料在用量表中不存在，则先创建
			JSONObject params = new JSONObject();
			params.put("aplPartNumber", partMaster.getNumber());
			List<APLQuantity> quantitys = AVLUtil.queryAPLQuantity(params);
			if(quantitys.size() <= 0) {
				WTHashSet _set = new WTHashSet();
				QuantityService.batchCreateAPLQuantity(partMaster, "", new BigDecimal(0), _set);
				if(_set.size() > 0) {
					PersistenceHelper.manager.save(_set);
				}
			}
			
			for(int i = 0 ; i < array.length(); i++) {
				obj = array.getJSONObject(i);
				String range = obj.getString(RANGE);//使用范围，内部名称
				//String historyLevel = obj.getString(HISTORYLEVEL); //历史等级
				String targetLevel = obj.getString(TARGETLEVEL); //进阶等级，一定会有值
//				String quan = obj.getString(QUANTITY);// 页面输入的总用量
				if(StringUtils.isNotEmpty(targetLevel)) { //当历史等级不等于进阶等级时，表示有变更
					APLQuantity quantity = AVLUtil.getAPLQuantity(partMaster.getPersistInfo().getObjectIdentifier().getId(), range);
					if(null !=quantity) {
						quantity.setProcesses(false);
						if("cancel".equals(route)) {
							quantity.setStatus(RangeChangeConstants.STATUS[1]);
						} else if("complete".equals(route)) {
							quantity.setStatus(RangeChangeConstants.STATUS[0]);
							quantity.setLevels(targetLevel);
						}
						set.add(quantity);
					}
					table.put(range, targetLevel); //APLQuantity有可能不存在，但实际物料属性需要去修改
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return table;
	}
	
	/**
	 * 封装数据：每天定时任务中待启动流程的范围用量
	 * @param quantitys
	 * @author xucr
	 * @CreateDate 2020年11月13日
	 */
	public static void getRangeChangeData(List<APLQuantity> quantitys) {
		/**
		 * 封装：
		 * 1、以APL材料为维度
		 * 2、一个APL材料有多个变更时，在一个流程中启动
		 * */
		if(null != quantitys && quantitys.size() > 0) {
			Map<WTPartMaster, JSONObject> maps = new HashMap<WTPartMaster, JSONObject>();
			/**
			 * Map
			 * 	key:wtpartmaster
			 * 	value:
			 * {
			 * 		ranges:u1,u2,u3
			 * 		data:[{
			 * 			range:u1,
			 * 			targetlevel:L1
			 * 			historylevel:L0
			 * 		}]
			 * }
			 * 
			 * */
			try {
				JSONObject all = null;
				JSONArray data = null;
				JSONObject dataInfo = null;
				String reanges = "";
				Map<String, String> rangeMap = AVLUtil.getIBARangeValue();
				Map<String,String> lenvlMap = EnumerationUtil.getEnumerationValues("Level"); //等级枚举
				for(APLQuantity quantity : quantitys) {
					dataInfo = new JSONObject();
					WTPartMaster master = (WTPartMaster) quantity.getPersistable().getObject();
					dataInfo.put(RANGE, quantity.getRanges());
					dataInfo.put(RANGE_VALUE, TMUtil.conversion(rangeMap.get(quantity.getRanges())));
					dataInfo.put(TARGETLEVEL, quantity.getLevelTo());
					dataInfo.put(TARGETLEVEL_VALUE, TMUtil.conversion(lenvlMap.get(quantity.getLevelTo())));
					dataInfo.put(HISTORYLEVEL, quantity.getLevels());
					dataInfo.put(HISTORYLEVEL_VALUE, TMUtil.conversion(lenvlMap.get(quantity.getLevels())));
					dataInfo.put(QUANTITY, quantity.getQuantity());
					
					if(maps.containsKey(master)) {
						all = maps.get(master);
						reanges = all.getString(RANGES) + ";" + quantity.getRanges();
						data = all.getJSONArray(DATA);
						data.put(dataInfo);
					} else {
						reanges = quantity.getRanges();
						data = new JSONArray();
						all = new JSONObject();
						data.put(dataInfo);
					}
					all.put(DATA, data);
					all.put(RANGES, reanges);
					maps.put(master, all);
					
				}
				//启动流程
				if(maps.size() > 0) {
					for(WTPartMaster mast : maps.keySet()) {
						WTPart part = PartUtil.getWTPartByNumber(mast.getNumber());
						JSONObject o = maps.get(mast);
						JSONArray array = o.getJSONArray(DATA);
						String ranges = o.getString(RANGES);
						RangeChangeProcess.startProcess(part, array, ranges.split(";"), RangeChangeConstants.PROCESSTYPE[0]);
					}
				}
			} catch (JSONException e) {
				e.printStackTrace();
			} catch (WTException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 得到文档下载地址
	 * @param pbo
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年7月27日
	 */
	public static String getDownUrl(ObjectReference self, WTObject primaryBusinessObject) throws WTException {
		/**
		 * APL材料审批流程
		 * */
		ReferenceFactory rf = new ReferenceFactory();
//		WTDocument doc = getReferenceDoc((WTPart)primaryBusinessObject);
		WTDocument doc = AVLUtil.getDoc((WTPart)primaryBusinessObject, "cn.tianma.APLValidationReport");//APL材料可能有很多参考文档
		String downUrl = "暂无下载地址";
		if(null != doc) {
			String baseHref = new URLFactory().getBaseHREF();
			/** 下载地址
			  http://plm-uat.tianma.cn/Windchill/servlet/AttachmentsDownloadDirectionServlet?
			  oid=OR:wt.doc.WTDocument:496962377&oid=OR:wt.content.ApplicationData:496962394&
			  role=PRIMARY
			  */
			ApplicationData primary = InterfaceService.getPrimaryContent(doc);
			if(null != primary) { 
				String docOid = rf.getReferenceString(doc);
				String applicatOid = rf.getReferenceString(primary);
				String docUrl = "servlet/AttachmentsDownloadDirectionServlet?oid=" + docOid 
						+ "&oid=" + applicatOid + "&role=PRIMARY";
				
				downUrl = "<a href="+baseHref + docUrl+">下载验证报告</a>";
			}
		}
		return downUrl;
	}
	
	/**
	 * 得到文档下载地址
	 * @param self
	 * @param primaryBusinessObject
	 * @param docType
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年11月11日
	 */
	public static String getDownUrl(ObjectReference self, WTObject primaryBusinessObject, String docType) throws WTException {
		/**
		 * APL材料进阶流程
		 * */
		ReferenceFactory rf = new ReferenceFactory();
		WTDocument doc = AVLUtil.getDoc((WTPart)primaryBusinessObject, docType);//APL材料可能有很多参考文档
		String downUrl = "暂无下载地址";
		if(null != doc) {
			String baseHref = new URLFactory().getBaseHREF();
			/** 下载地址
			  http://plm-uat.tianma.cn/Windchill/servlet/AttachmentsDownloadDirectionServlet?
			  oid=OR:wt.doc.WTDocument:496962377&oid=OR:wt.content.ApplicationData:496962394&
			  role=PRIMARY
			  */
			ApplicationData primary = InterfaceService.getPrimaryContent(doc);
			if(null != primary) { 
				String docOid = rf.getReferenceString(doc);
				String applicatOid = rf.getReferenceString(primary);
				String docUrl = "servlet/AttachmentsDownloadDirectionServlet?oid=" + docOid 
						+ "&oid=" + applicatOid + "&role=PRIMARY";
				
				downUrl = "<a href="+baseHref + docUrl+">下载</a>";
			}
		}
		return downUrl;
	}
	
	/**
	 * 创建验证文档
	 * @param filePath
	 * @return
	 * @throws Exception
	 * @author xucr
	 * @CreateDate 2020年7月24日
	 */
	public static WTDocument createReportDoc(String fileName, String filePath, String des) throws Exception {
		String number = DBUtil.getNextValue("WTDOCUMENTID_seq", 10);
		WTContainer container = MaterialsApplicationService.getContainerByName("APL材料报告库");
		Folder folder = GenericUtil.getFolder("/Default/验证报告", container);
		
		WTDocument doc = GenericUtil.createWTDocument(number, fileName, "cn.tianma.APLValidationReport", container, folder, des, null, filePath);
		
		return doc;
	}
	
	/**
	 * 创建文档与部件的关系
	 * @param filePath 文档路径
	 * @param name 文档名称
	 * @param wid 流程oid
	 * @return
	 * @throws Exception
	 * @author xucr
	 * @CreateDate 2020年7月24日
	 */
	public static WTDocument createDocAndLink(String filePath, String name, String wid, String oid) throws Exception {
		WfProcess process = (WfProcess) MyUtil.getObjectByOid(wid);
		WTPart part = (WTPart) TMUtil.oid2Obj(oid);
		WTDocument doc = null;
		
		/**
		 * 逻辑说明：
		 * 1. 只会上载一份参考文档
		 * 2. 重复上载时，会更新已有参考文档的主要内容
		 * */
		QueryResult qr = PartDocServiceCommand.getAssociatedReferenceDocuments(part);//参考文档
		if(qr.size() > 0) {//存在参考文档
			doc = getReferenceDoc(part);
			File file = new File(filePath);
			InputStream io = new FileInputStream(file);
			CreateDocAndDescribeLink.replacePrimaryContent(doc, io, file.getName());
		} else {
			ReferenceFactory rf = new ReferenceFactory();
			doc = createReportDoc(name, filePath, rf.getReferenceString(process));//将相关流程oid写到文档描述中
			
			creatDocuments.createRefLink(part, doc);//构建文档参考关系
			
		    process = (WfProcess)PersistenceHelper.manager.save(process);
		}
		return doc;
	}

	/**
	 * 根据流程获id和文档,产生文档下载连接,并更新到活动节点的变量中
	 * @param wid
	 * @param document
	 * @throws Exception
	 */
	public static void updateLinkInfo(String wid,WTDocument document) throws Exception {
		if(StringUtils.isNotBlank(wid)) {
			WfProcess process = (WfProcess) MyUtil.getObjectByOid(wid);
			QueryResult queryResult = WorkflowUtil.getActiveAssignedActivities(process);
			WfAssignedActivity assignedActivity = null;
			if (queryResult != null) {
				while (queryResult.hasMoreElements()) {
					WfAssignedActivity tempActivity = (WfAssignedActivity) queryResult.nextElement();
					if ("AVL材料提交".equals(tempActivity.getName())) {
						assignedActivity = tempActivity;
						break;
					}
				}
			}
			//// TODO: 2021/8/8 确定活动节点名称,和流程变量key
			String downUrl = "暂无下载地址";
			if (null != document) {
				String baseHref = new URLFactory().getBaseHREF();
				/** 下载地址
				 http://plm-uat.tianma.cn/Windchill/servlet/AttachmentsDownloadDirectionServlet?
				 oid=OR:wt.doc.WTDocument:496962377&oid=OR:wt.content.ApplicationData:496962394&
				 role=PRIMARY
				 */
				document= (WTDocument) PersistenceHelper.manager.refresh(document);
				ApplicationData primary = InterfaceService.getPrimaryContent(document);
				if (null != primary) {
					wt.fc.ReferenceFactory rf = new wt.fc.ReferenceFactory();
					String docOid = rf.getReferenceString(document);
					String applicatOid = rf.getReferenceString(primary);
					String docUrl = "servlet/AttachmentsDownloadDirectionServlet?oid=" + docOid
							+ "&oid=" + applicatOid + "&role=PRIMARY";
					downUrl = "<a href=" + baseHref + docUrl + ">"+primary.getFileName()+"</a>";
				}
			}
			if (assignedActivity != null) {
				ProcessData context = assignedActivity.getContext();
				context.setValue("reportUrl", downUrl);
				assignedActivity.setContext(context);
				PersistenceHelper.manager.save(assignedActivity);
			}
		}
	}

	/**
	 * 获取参考文档，仅此一份
	 * @param part
	 * @return
	 * @throws WTException
	 * @author xucr
	 * @CreateDate 2020年7月27日
	 */
	public static WTDocument getReferenceDoc(WTPart part) throws WTException {
		QueryResult qr = PartDocServiceCommand.getAssociatedReferenceDocuments(part);//参考文档
		WTDocument doc = null;
		while (qr.hasMoreElements()) {
			doc = (WTDocument) qr.nextElement();
			break;
		}
		return doc;
	}
	
	/**
	   * 判断是否有删除的数据，若存在删除的数据，设置其isProcess是否流程中为false
	   * 
	   * @param self
	   * @throws JSONException
	   * @throws WTPropertyVetoException
	   * @throws WTException
	   */
	public static void delUpdateISProcess(JSONArray array, String firstRange, WTPartMaster master)
	      throws JSONException, WTPropertyVetoException, WTException {
	    // 更新数据与首次发起流程数据对比，取差异
	    JSONObject obj = null;
	    
	    //首次发起流程中的使用范围集合：因为这些数据， 被设置成了流程中
	    String[] firstRanges = firstRange.split(",");
	    List<String> listRanges = new ArrayList<String>( Arrays.asList(firstRanges));

	    // 得到changeData中的范围集合
	    List<String> list = new ArrayList<String>();
	    for (int i = 0; i < array.length(); i++) {
	    	obj = array.getJSONObject(i);
	    	String ranges = obj.getString(RANGE);
	    	list.add(ranges);
	    	listRanges.remove(ranges);
	    }
	    // 从使用范围中移除changeData中存在的范围，并设置其是否流程中为false。
	    if (null != listRanges && listRanges.size() > 0) {
	    	Iterator it = listRanges.iterator();
	    	WTHashSet set = new WTHashSet();
	    	while (it.hasNext()) {
		        String range = (String) it.next();
		        APLQuantity quantity = AVLUtil.getAPLQuantity(master.getPersistInfo().getObjectIdentifier().getId(), range);
		        if (null != quantity) {
		        	quantity.setProcesses(false);
		        }
		        set.add(quantity);
	    	}
		    if (set.size() > 0) {
		    	PersistenceHelper.manager.save(set);
		    }
	    }
	}
}
